<?php


namespace common\services;


use common\exception\CheckException;
use common\models\GoldDetail;
use common\models\PostOrder;
use common\models\Post;
use common\models\PostPrice;
use common\models\User;

class PostOrderService
{

    /**
     * 购买视频观看权限
     * @param User $user
     * @param $goodId
     * @return bool
     * @throws \Throwable
     */
    public static function createOrder(User $user, $goodId)
    {
        bcscale(6);
        $transaction = \Yii::$app->getDb()->beginTransaction();
        try {
            //查询产品售价
            $goodInfo = Post::find()
                ->select([
                    'post.id as good_id',
                    'post.content',
                    'post.video_info',
                    'post_price.price',
                    'post_price.origin_price',
                    'post.work_attr'
                ])
                ->leftJoin(PostPrice::tableName(), 'post_price.post_id = post.id')
                ->where(['post.id' => $goodId])
                ->andWhere(['post.work_attr' => [Post::WORK_ATTR_VIDEO, Post::WORK_ATTR_VR]])
                ->andWhere(['post.is_show' => Post::SHOW_STATUS_TRUE, 'post.is_del' => Post::DEL_STATUS_FALSE])
                ->asArray()
                ->one();

            if (empty($goodInfo) || empty($goodInfo['price'])) {
                throw new CheckException('', 43001);
            }

            //判断用户是否已购买
            $isBuy = PostOrder::find()->where(['user_id' => $user->id, 'good_id' => $goodId, 'goods_type' => [PostOrder::ORDER_TYPE_VIDEO, PostOrder::ORDER_TYPE_VR]])->one();
            if ($isBuy) {
                throw new CheckException('', 43000);
            }

            if (bccomp($goodInfo['price'], $user->amount) == 1) {
                throw new CheckException('', 2000);
            }

            $goodName = $goodInfo['content'];

            $goodDescInfo = [
                'good_name' => $goodName,
                'good_type' => $goodInfo['work_attr'],
                'good_price' => $goodInfo['price'],
                'good_origin_price' => $goodInfo['origin_price'],
                'good_info' => json_decode($goodInfo['video_info'], true)
            ];

            $beforeGold = $user->amount;


            //生成订单
            $order = new PostOrder();
            $order->user_id = $user->id;
            $order->amount = $goodInfo['price'];
            $order->goods_type = $goodInfo['work_attr'];
            $order->good_id = $goodInfo['good_id'];
            $order->order_no = self::makeOrderNo();
            $order->good_name = '视频观看:' . $goodInfo['content'];
            $order->good_info = json_encode($goodDescInfo);
            $order->status = PostOrder::STATUS_SUCCESS;

            //售价为0时，不用扣余额
            $subAmountRes = (bccomp($goodInfo['price'], 0) === 0) ? true : $user->updateCounters(['amount' => -$goodInfo['price']]);

            if ($order->save() && $subAmountRes) {
                //金币明细
                $goldDetail = new GoldDetail();
                $goldDetail->gold = -$goodInfo['price'];
                $goldDetail->user_id = $user->id;
                $goldDetail->type = GoldDetail::TYPE_BUY_VIDEO;
                $goldDetail->before_action_gold = $beforeGold;
                $goldDetail->after_action_gold = $user->amount;
                $goldDetail->ref_id = $order->id;
                if ($goldDetail->save()) {
                    $transaction->commit();
                    return true;
                }
            }
            $transaction->rollBack();
            throw new CheckException('', 43002);
        } catch (\Throwable $throwable) {
            $transaction->rollBack();
            throw $throwable;
        }
        return false;
    }

    /**
     * 订单号
     * @param int $moreCharNum
     * @return string
     */
    private static function makeOrderNo($moreCharNum = 2)
    {
        $endStr = '';
        for ($i = 1; $i <= $moreCharNum; $i++) {
            $endStr .= chr(rand(65, 90));
        }
        list($usec, $sec) = explode(" ", microtime());
        return 'G' . date('ymdHis', $sec) . substr($usec, 2, 6) . $endStr;

    }
}